#include "can_driver.h"
#include <iostream>

CanDriver::CanDriver()
{
    // 启动CAN通道
   _cfg.dwAccCode = 0;
   _cfg.dwAccMask = 0xffffffff;
   _cfg.nFilter = 0;  // 滤波方式(0表示未设置滤波功能,1表示双滤波,2表示单滤波)
   _cfg.bMode = 0;    // 工作模式(0表示正常模式,1表示只听模式)
   _cfg.nBtrType = 1; // 位定时参数模式(1表示SJA1000,0表示LPC21XX)
   ready = false;
}

void CanDriver::set_baudrate(uint16_t baudrate)
{
    /**
    * BTR0:BTR1 
    *  0014-1M 
    *  0016-800K 
    *  001C-500K 
    *  011C-250K 
    *  031C-12K 
    *  041C-100K 
    *  091C-50K 
    *  181C-20K 
    *  311C-10K 
    *  BFFF-5K
    */
   unsigned char baud[2] = {0};

   if (baudrate == 50)
   {
      baud[0] = 0x09;
      baud[1] = 0x1C;
   }
   else if (baudrate == 100)
   {
      baud[0] = 0x04;
      baud[1] = 0x1C;
   }
   else if (baudrate == 250)
   {
      baud[0] = 0x01;
      baud[1] = 0x1C;
   }
   else if (baudrate == 500)
   {
      baud[0] = 0x00;
      baud[1] = 0x1C;
   }

   _cfg.dwBtr[0] = baud[0]; // BTR0   0014 -1M 0016-800K 001C-500K 011C-250K 031C-12K 041C-100K 091C-50K 181C-20K 311C-10K BFFF-5K
   _cfg.dwBtr[1] = baud[1]; // BTR1
   _cfg.dwBtr[2] = 0;
   _cfg.dwBtr[3] = 0;
}

bool CanDriver::init()
{
    this->init(250);
}

bool CanDriver::init(uint16_t baudrate)
{
    if(ready)
    {
        std::cout << "Device Already Open" << std::endl;
        return true;
    }

    if((HANDLE = CAN_DeviceOpen(ACUSB_132B, 0, 0)) == 0)
    {
        std::cout << "open deivce error" << std::endl;
        return false;
    }
    set_baudrate(baudrate);
    if (CAN_ChannelStart(HANDLE, 0, &_cfg) != CAN_RESULT_OK)
    {
        std::cout << "Start CAN 0 error" << std::endl;
        return false;
    }    
    ready = true;
    std::cout << "Can Driver Ready." << std::endl;
}

void CanDriver::de_init()
{
    std::cout << "Close Can Driver" << std::endl;
    CAN_ChannelStop(HANDLE, 0);
    CAN_DeviceClose(HANDLE);
    ready = false;
}

bool CanDriver::set_terminal_resistor()
{
    /* Enable Terminal Resistor
    * FE : 1, FF : 1 Enalbe
    * FE : 1, FF : 0 Disable
    */
    static unsigned char resistor = 1;
    if (CAN_WriteRegister(HANDLE, 0, 0xFE, &resistor, 1) != CAN_RESULT_OK)
        return false;

    if (CAN_WriteRegister(HANDLE, 0, 0xFF, &resistor, 1) != CAN_RESULT_OK)
        return false;

    return true;
}